#include "StdAfx.h"
#include "ConfigSheet.h"

using namespace Pattern;

Pattern::ConfigSheet::ConfigSheet(void)
{
	
}

Pattern::ConfigSheet::~ConfigSheet(void)
{
	
}

bool Pattern::ConfigSheet::Add( ConfigItem& value )
{
	if(value.host==0 && !ContainsName(value.name))
	{
		value.host=this;
		itemList.push_back(value);
		return true;
	}

#if _DEBUG
	throw new std::exception("can not add a item which already belonged to a sheet or have a invalidate name");
#endif

	return false;
}

bool Pattern::ConfigSheet::Remove( const ObjectName& key )
{
	for(PropertyItemList::iterator it = itemList.begin();it!=itemList.end();it++)
	{
		if(it->name==key)
		{
			it->host=0;
			itemList.erase(it);
			return true;
		}
	}

	return false;
}

Pattern::Uint Pattern::ConfigSheet::Count() const
{
	return itemList.size();
}

bool Pattern::ConfigSheet::IsEmpty() const
{
	return itemList.empty();
}

bool Pattern::ConfigSheet::ContainsName( const ObjectName& key ) const
{
	for(PropertyItemList::const_iterator it = itemList.begin();it!=itemList.end();it++)
	{
		if(it->name==key)
		{
			return true;
		}
	}

	return false;
}

ConfigItem& Pattern::ConfigSheet::GetByIndex( Uint index )
{
	return itemList.at(index);
}

ConfigItem& Pattern::ConfigSheet::GetByName( const ObjectName& key )
{
	for(PropertyItemList::iterator it = itemList.begin();it!=itemList.end();it++)
	{
		if(it->name==key)
		{			
			return *it;
		}
	}
	
	return ConfigItem::Empty();
}

bool Pattern::ConfigSheet::NotifyItemNameChanging( const ObjectName& newName )
{
	return !ContainsName(newName);
}

void Pattern::ConfigSheet::NotifyItemNameChanged( ConfigItem* item )
{
	for each(Listener* li in listeners)
	{
		li->OnItemNameChanged(item);
	}
}

void Pattern::ConfigSheet::NotifyItemGroupChanged( ConfigItem* item )
{
	for each(Listener* li in listeners)
	{
		li->OnItemGroupChanged(item);
	}
}

void Pattern::ConfigSheet::NotifyItemValueChanged( ConfigItem* item )
{
	for each(Listener* li in listeners)
	{
		li->OnItemValueChanged(item);
	}
}

void Pattern::ConfigSheet::AddListener( Listener* listener )
{
	listeners.push_back(listener);
}

void Pattern::ConfigSheet::RemoveListener( Listener* listener )
{
	listeners.erase(std::find(listeners.begin(),listeners.end(),listener));
}

bool Pattern::ConfigItem::operator !=(const Pattern::ConfigItem &another) const
{
	return name != another.name && group != another.group && value != another.value;
}

bool Pattern::ConfigItem::operator ==(const Pattern::ConfigItem &another) const
{
	return name == another.name && group == another.group && value == another.value;
}

ConfigItem& Pattern::ConfigItem::Empty()
{
	static ConfigItem emptyitem;
	if(!emptyitem.isEmpty())emptyitem.Clear();
	return emptyitem;
}

bool Pattern::ConfigItem::isEmpty() const
{
	return value.empty()&&name.IsEmpty()&&group.IsEmpty();
}

void Pattern::ConfigItem::Clear()
{
	name.Clear();
	group.Clear();
	value.clear();
}

Pattern::ObjectName Pattern::ConfigItem::Name() const
{
	return name;
}

void Pattern::ConfigItem::Name(const Pattern::ObjectName& val )
{
	if(name!=val)
	{
		if(host!=0 && !host->NotifyItemNameChanging(val))
		{
#if _DEBUG
			throw new std::exception("new name is not allowed");
#endif
			return;
		}

		name = val; 
		if(host!=0)
			host->NotifyItemNameChanged(this);
	}
}

Pattern::ObjectName Pattern::ConfigItem::Group() const
{
	return group;
}

void Pattern::ConfigItem::Group(const Pattern::ObjectName& val )
{
	if(group!=val)
	{
		group = val; 
		if(host!=0)
			host->NotifyItemGroupChanged(this);
	}
}

std::string Pattern::ConfigItem::Value() const
{
	return value;
}

void Pattern::ConfigItem::Value(const std::string& val )
{
	if(value!=val)
	{
		value = val; 
		if(host!=0)
			host->NotifyItemValueChanged(this);
	}
}

Pattern::ConfigItem::ConfigItem():host(0)
{
}